﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Web;

namespace WebDiagnostics.Diagnosers.DatabaseConnectivity
{
    internal class DatabaseConnectivityDiagnoserDescriptor : DiagnoserDescriptor
    {
        public override Type DiagnoserType
        {
            get { return typeof(DatabaseConnectivityDiagnoser); }
        }

        public override string DisplayName
        {
            get { return "Database Connectivity"; }
        }
    }

    public class DatabaseConnectivityDiagnoser : IDiagnoser
    {
        public Diagnosis Diagnose(HttpContextBase context)
        {
            IEnumerable<DatabaseQuery> databaseQueries = BuildDatabaseQueriesFromConnections();
            var results = GetDatabaseQueryResults(databaseQueries);

            return new DatabaseConnectivityDiagnosis(results);
        }

        private static IEnumerable<DatabaseQuery> BuildDatabaseQueriesFromConnections()
        {
            IEnumerable<SqlConnectionStringQuery> queries =
                from connectionSetting in ConfigurationManager.ConnectionStrings.Cast<ConnectionStringSettings>()
                where connectionSetting.ProviderName == "System.Data.SqlClient"
                select new SqlConnectionStringQuery(connectionSetting);

            return queries;
        }

        internal IEnumerable<DatabaseQueryResult> GetDatabaseQueryResults(IEnumerable<DatabaseQuery> queries)
        {
            foreach (var databaseQuery in queries)
            {
                DatabaseQueryResult result;
                try
                {
                    result = databaseQuery.Execute();
                }
                catch (Exception e)
                {
                    result = new DatabaseQueryResult(
                        databaseQuery.Name, 
                        DatabaseQueryResultKind.Failed, 
                        e.ToString());
                }

                yield return result;
            }
        }
    }
}
